package com.zyx.spring5msb.iocanno.controller;

import com.zyx.spring5msb.iocanno.service.PersonService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;

/**
 * @author Yaxi.Zhang
 * @since 2021/9/28 10:46
 * desc: Spring IOC 的 自动注入
 *      通过@AutoWired注解能够完成自动注入的功能
 *      是按照什么方式进行自动注入的呢？
 *      默认情况下是按照ByType来进行装配的,如果找到直接赋值, 找不到报错
 *      如果有多个类型一样的bean对象, 此时会按照id来进行查找, 默认的id是类名首字符小写
 *      如果找到了直接注入, 如果找不到那么就报错
 *
 *      如果你想通过名字进行查找, 可以自己规定名称, 使用注解@Qualifier
 *
 *      当@AutoWired添加到方法上的时候, 此方法在创建对象的时候会默认调用, 同时方法中的参数会进行自动装配
 *
 *      `@Qualifier` 注解也可以定义在方法的参数列表中,可以指定当前属性的id名称 使用@Resource可以完成跟@AutoWired相同的功能, 但是要注意他们之间的区别
 *      1.@Resource是jdk提供的功能, @AutoWired是spring提供的功能
 *      2.@Resource可以在其他框架中使用, 而@AutoWired只能在spring中使用
 *           换句话说: @Resource扩展性好, 而@AutoWired支持的框架比较单一
 *      3.@Resource是按照名称进行装配的, 如果名字找不到, 那么就使用类型
 *           而@AutoWired是按照类型进行装配, 如果类型找不到那么久使用名字进行查找
 *           注意: 由于 @Resource 不是Spring注解, 所以如果名称与类型不匹配时会报错, 例如
 *               `@Resource`
 *               `@Qualifier(value = "personService2")`
 *               private PersonService2 personService
 *           将会报错,这是由于按照名称`@Resource`已经注入了PersonService类型数据 而
 *               `@Autowired`
 *               `@Qualifier(value = "personService2")`
 *               private PersonService2 personService
 *           则能够正常运行, 这是由于@Autowired按照类型注入PersonService2类型数据, 与`@Qualifier`中的名称吻合
 *           但是使用
 *               `@Resource`
 *               `@Qualifier(value = "personService")`
 *               private PersonService personService22
 *           是可以正常运行的, 这是由于personService22没有匹配成功, 因此会从 `@Qualifier` 中匹配PersonService类型数据
 *       总结一下:
 *           1) `@Autowired`中只需要 `@Qualifier`的value值与 待注入的类 类型一致即可, 无论该类型的变量名是什么
 *           2) `@Resource`中`@Qualifier`的value值与 待注入的类 类型一致时, 还需要以下条件:
 *                   ① 待注入的类的变量名 与 @Qualifier的 value 相同
 *                   ② 待注入的类的变量名 与 @Qualifier的 value 不相同, 且该变量名没有类与之对应(如果该变量名有 类型与之匹配, 将会报错)
 */
@Controller
public class PersonController {

    @Autowired
    private PersonService personService;

    public void save() {
        personService.save();
    }

}
